
#ifndef __RSP_OBJREF__HEADER_FILE__
#define __RSP_OBJREF__HEADER_FILE__

#include "rsp.h"

////////////////////////////////////////////////////////////////////////////////
template <class T, bool OWNING>
class rsp_dynarray : public dynarray<T*>
{
public:

    typedef typename dynarray<T*>::binstream_dereferencing_container  container;

    container get_container()
    {
        container bc( *this, this->size() );
        return bc;
    }


    rsp_dynarray()
    {
    }

    explicit rsp_dynarray( uint n )
    {
        this->need_newc(n);
    }

    ~rsp_dynarray()
    {
    }


    void init( uint n )
    {
        DASSERT( OWNING );
        uint ts = this->size();

        this->needc(n);
        for( uint i=ts; i<n; ++i )
            this->_ptr[i] = (T*) new typename type_select<OWNING,T,int>::type;// T;
    }

    rsp_dynarray& operator = (const rsp_dynarray& src)
    {
        DASSERT( src.size() == 0  ||  Gactive_controller->client_side() );

        //map pointers to ref objects to pointers to bound objects
        this->needc( src.size() );

        for( uint i=0; i<this->size(); ++i )
        {
            if(!OWNING)
                this->_ptr[i] = 0;

            if( src[i] == 0 )  continue;

            rsp_c_object_state* os = rsp_c_object_state::get_from_ptr( src[i] );
            DASSERT(os);
            //DASSERT( OWNING  ||  os->

            this->_ptr[i] = (T*) os->set_bound_object( 0, true );
            //_array[i] = os->bound_object_ptr();
        }

        return *this;
    }





    ////////////////////////////////////////////////////////////////////////////////
    void rsp_attach( rsp_s_connector& ctrl )
    {
        DASSERT( OWNING );
        for( uint i=0; i<this->size(); ++i )
            this->_ptr[i]->rsp_attach(ctrl);
    }

    void rsp_detach( rsp_s_connector& ctrl )
    {
        DASSERT( OWNING );
        for( uint i=0; i<this->size(); ++i )
            this->_ptr[i]->rsp_detach(ctrl);
    }

    ///Generate the differential update into the binstream
    void stream_out( binstream& bin ) const
    {
        uint n = this->size();
        bin << (ushort)n;

        for( uint i=0; i<n; ++i )
        {
            bin << (ushort)this->_ptr[i]->oid();
        }
    }

    void stream_in( binstream& bin )
    {
        DASSERT( Gactive_controller->client_side() );
        //DASSERT( _flags != INTERPOLATED );

        ushort n;
        bin >> n;

        this->needc(n);

        for( uint i=0; i<n; ++i )
        {
            ushort o;
            bin >> o;

            rsp_c_object_state* os = rsp_c_object_state::get_from_oid(o);
            DASSERT(os);

            this->_ptr[i] = (T*)os->ref_object_ptr();
        }

        //_flags = REFERENCE;
    }

protected:


};


/*
////////////////////////////////////////////////////////////////////////////////
template <class T>
class rsp_objref
{
    //CL0
    T*  _obj;

public:

    static token class_name()       { static token _T = "$objref"; return _T; }


    T* operator -> () const         { return _obj; }
    T& operator * () const          { return *_obj; }

    bool operator == (T* obj) const { return _obj == obj; }

    bool is_set() const             { return _obj != 0; }

    T* ptr() const                  { return _obj; }


    void set( T* obj, rsp_base* base, int cluster )
    {
        _obj = obj;
        //DIRTY_CLUSTER(0);
        base->_rsp_destmask |= 1<<cluster;
    }

    rsp_objref()
    {
        _obj = 0;
    }

    rsp_objref& operator = (const rsp_objref& src)
    {
        if( src._obj == 0 )
            _obj = 0;
        else
        {
            DASSERT( Gactive_controller->client_side() );
            rsp_c_object_state* os = ((rsp_c_controller*)Gactive_controller)->find_object( src._obj );
            DASSERT(os);

            _obj = (T*)os->bound_object_ptr();
        }
        return *this;
    }

    void replicate( rsp_s_update& rvu )
    {
        binstream* bin = rvu.check_state_change();
        if(bin)   //if the state changed
        {
            uint n = UMAX;
            if(_obj)
            {
                n = rvu._ctrl->view_find(_obj);
                RASSERT( n != UMAX );
            }

            (*bin) << (ushort)n;
        }
    }

    void replicate( rsp_c_update& rvu )
    {
        binstream* bin = rvu.apply_state_change();
        if(bin)   //if the state changed
        {
            ushort n;
            (*bin) >> n;
            if( n == WMAX )
                _obj = 0;
            else
            {
                rsp_c_object_state* rs = rvu._ctrl->get_object(n);
                _obj = (T*) rs->ref_object_ptr();
            }
        }
    }
};
*/


#endif //__RSP_OBJREF__HEADER_FILE__
